package com.java.thread;
import java.util.LinkedList;
import java.util.List;

/**
 * 生产者消费者模式
 * 设计一个客户端线程和一个服务器线程，客户端线程不断发送请求给服务器线程，服务器线程不断处理请求，
 * 当请求队列为空时(当条件不满足)，服务器线程就必须等待，直到客户端发送了请求(条件满足),服务端线程被唤醒
 * @author jack
 *
 */
public class MainThread {
	private final static int REQUEST_COUNT=2;
	public static void main(String[] args) {
		Queue queue = new Queue();
		ServerThread serverThread = new ServerThread(queue);
		serverThread.setName("ServerThread");
		serverThread.start();
		ClientThread[] clients = new ClientThread[3];
		for(int i=0;i<clients.length;i++){
			clients[i] = new ClientThread(queue,"ClientThread-"+i,REQUEST_COUNT);
			clients[i].start();
		}
		
		
		while(true){//主线程监听server和client是否工作完毕，完毕则让server结束，serverThread.shutdown();
			int count=0;
			int c = clients.length;
			for(int i=0;i<clients.length;i++){
				if(!clients[i].isAlive()){//if(clients[i].isIdle()){
					count+=1;
				}
			}
			if(count == c && serverThread.getProcessCount() == (c*REQUEST_COUNT)){
				break;
			}
		}
		
		serverThread.shutdown();
		
	}

}


class Request{
	private String name;
	public Request(String name){
		this.name = name;
	}
	public String toString(){
		return "Request_"+name;
	}
	
}
/**
 * 定义队列--共享资源
 * @author jack
 *
 */
class Queue{
	private List<Request> queue = new LinkedList<Request>();
	//服务器接收,处理请求(消费)
	public synchronized Request receiveRequest(){
		while(queue.size() == 0){
			try {
				System.out.println("请求队列为空时，服务器线程须等待...");
				this.wait();
			} catch (InterruptedException e) {
				System.out.println("工作已做完，不用再休息了，可以直接回家了");
				e.printStackTrace();
				return null;
			}
		}
		Request request = (Request)queue.remove(0);
		System.out.println(Thread.currentThread().getName()+"   接收一个请求:"+request);
		return request;
	}
	//客户端发送，放入请求(生产)
	public synchronized void sendRequest(Request request){
		queue.add(request);
		System.out.println(Thread.currentThread().getName()+" 发送一个请求:"+request);
		this.notifyAll();//唤醒服务器线程
	}
	
}

/**
 * 客户端线程，生产者：生产请求
 * @author jack
 */
class ClientThread extends Thread{
	private Queue queue;
	private String clientName;
	private int count=0;
	public ClientThread(Queue queue,String clientName,int count){
		this.queue = queue;
		this.clientName = clientName;
		this.count = count;
		this.setName(clientName);
	}
	public String toString(){
		return "["+clientName+"]";
	}
	
	public void run(){
		for(int i=0;i<count;i++){
			Request request = new Request(""+i);
			queue.sendRequest(request);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("客户端线程结束...");
	}
}

/**
 * 服务端线程，消费者：消费请求
 * @author jack
 */
class ServerThread extends Thread{
	private int count=0;
	private boolean stop = false;
	private Queue queue;
	public ServerThread(Queue queue){
		this.queue = queue;
	}
	
	public void shutdown(){
		stop = true;
		this.interrupt();
		try {
			this.join();
		} catch (InterruptedException e) {
			//报异常的原因是线程已经处于阻塞状态了，已经失去了cpu,如果还调用interrupt()要求改变中断状态抛出。
			System.out.println("报异常的原因是线程已经处于阻塞状态了，已经失去了cpu,如果还调用interrupt()要求改变中断状态抛出");
			e.printStackTrace();
		}
	}
	
	public int getProcessCount(){
		return this.count;
	}
	
	public void run(){
		while(!stop){
			Request request = queue.receiveRequest();
			if(request!=null){
				count+=1;
			}
			try {
				sleep(10000);
			} catch (InterruptedException e) {
				System.out.println("捕获到InterruptedException说明调用了stop方法，线程结束");
				e.printStackTrace();
			}
		}
		System.out.println("[ServerThread] isStop:"+stop);
		System.out.println("[ServerThread] shutdown.");
		System.out.println("[本次服务器线程处理请求数量]:"+this.count);
		
	}
	
}